package com.rt.easyjava.common.utils.others;

import com.google.common.base.Strings;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;


public class DateUtils {

    public static final String FORMAT_FULL = "yyyyMMddHHmmssSSS";

    /**
     * 默认日期格式
     */
    public static final String DATE_Y_M_D_8 = "yyyy-MM-dd";
    public static final String DATE_YMDHMS_SPLIT_14 = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_YMD_8 = "yyyyMMdd";
    public static final String DATE_YM_6 = "yyyyMM";
    public static final String DATE_YMDHSM_14 = "yyyyMMddHHssmm";
    public static final String DATE_YMDHMS_14 = "yyyyMMddHHmmss";
    public static final String DATE_YMDSMH_14 = "yyyyMMddssmmHH";
    public static final String DATETO6BITYMD = "yyMMdd";

    /**
     * 年月日时分秒毫秒,作为业务ID使用
     */
    public static String getBusinessId() {
        String result = getToDay(FORMAT_FULL);
        return result + "" + (((Math.random() * 100000) + "").substring(0, 4));
    }

    /**
     * 得到今天指定格式的日期
     *
     * @param format1 指定格式
     * @return 当天日期
     */
    public static String getToDay(String format1) {
        java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(
                format1);
        return format.format(new Date());
    }

    public static String beforeDate(String strFormat) {
        java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(
                strFormat);
        Calendar cal = DateTool.getCalendarInstance();
        cal.add(Calendar.DATE, -1);

        return format.format(cal.getTime());
    }

    /**
     * 功能：输出上个指定时间周期指定日期格式的日期数据
     *
     * @param nTimeType 如：Calendar.DATE、Calendar.MONTH
     * @param strFormat 如："yyyy-MM-dd"
     * @return
     */
    public static String beforeTime(int nTimeType, String strFormat) {
        java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(
                strFormat);
        Calendar cal = DateTool.getCalendarInstance();
        cal.add(nTimeType, -1);

        return format.format(cal.getTime());
    }

    /*****
     * 功能：转换日期类型
     *
     * @param strDate
     * @param nType
     *            类型：0--8位日期类型转为10位日期类型，20080808-->2008-08-08 1--10位日期类型转为8位日期类型
     * @return
     */
    public static String convert(String strDate, int nType) {
        StringBuffer sbDate = new StringBuffer();

        switch (nType) {
            case 0:
                sbDate.append(strDate.substring(0, 4)).append("-").append(
                        strDate.substring(4, 6)).append("-").append(
                        strDate.substring(6, 8));
                break;
        }

        return sbDate.toString();
    }

    public static String currentDate(String strFormat) {
        java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(
                strFormat);
        Calendar cal = DateTool.getCalendarInstance();

        return format.format(cal.getTime());
    }

    public static String formatDate(Date date, String strFormat) {
        java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(
                strFormat);
        return format.format(date.getTime());
    }

    public static String currentDayOfMonthStr() {
        Calendar cal = DateTool.getCalendarInstance();
        int currDay = cal.get(Calendar.DAY_OF_MONTH);
        String strTmp = "0" + String.valueOf(currDay);
        return strTmp.substring(strTmp.length() - 2, strTmp.length());
    }

    public static String currentMonthStr() {
        Calendar cal = DateTool.getCalendarInstance();
        int currMonth = cal.get(Calendar.MONTH) + 1;
        String strTmp = "0" + String.valueOf(currMonth);
        return strTmp.substring(strTmp.length() - 2, strTmp.length());
    }

    /**
     * 功能：输出当前时间指定日期格式的日期数据
     *
     * @param strFormat 如："yyyy-MM-dd"
     * @return
     */
    public static String currentTime(String strFormat) {
        java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(
                strFormat);
        Calendar cal = DateTool.getCalendarInstance();

        return format.format(cal.getTime());
    }

    public static String currentWeekDayCNStr() {
        Calendar cal = DateTool.getCalendarInstance();
        int currWeekDay = cal.get(Calendar.DAY_OF_WEEK);
        String sWeekDay = null;
        switch (currWeekDay) {
            case 1:
                sWeekDay = "星期日";
                break;
            case 2:
                sWeekDay = "星期一";
                break;
            case 3:
                sWeekDay = "星期二";
                break;
            case 4:
                sWeekDay = "星期三";
                break;
            case 5:
                sWeekDay = "星期四";
                break;
            case 6:
                sWeekDay = "星期五";
                break;
            case 7:
                sWeekDay = "星期六";
                break;
        }

        return sWeekDay;
    }

    public static String currentYearStr() {
        Calendar cal = DateTool.getCalendarInstance();
        int currYear = cal.get(Calendar.YEAR);
        return String.valueOf(currYear);
    }


    public static String nextDate(String strFormat) {
        java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(
                strFormat);
        Calendar cal = DateTool.getCalendarInstance();
        cal.add(Calendar.DATE, 1);

        return format.format(cal.getTime());
    }

    public static String nextDate(String strDate, String strFormat)
            throws ParseException {
        java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(
                strFormat);
        Calendar cal = DateTool.getCalendarInstance();
        Date date = format.parse(strDate);
        cal.setTime(date);
        cal.add(Calendar.DATE, 1);

        return format.format(cal.getTime());
    }

    /**
     * 功能：输出下个指定时间周期指定日期格式的日期数据
     *
     * @param nTimeType 如：Calendar.DATE、Calendar.MONTH
     * @param strFormat 如："yyyy-MM-dd"
     * @return
     */
    public static String nextTime(int nTimeType, String strFormat) {
        java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(
                strFormat);
        Calendar cal = DateTool.getCalendarInstance();
        cal.add(nTimeType, 1);

        return format.format(cal.getTime());
    }

    public static String parseDateCN(String strDate) {
        StringTokenizer ken = new StringTokenizer(strDate, "-");
        StringBuffer sb = new StringBuffer();
        if (ken.hasMoreElements()) {
            sb.append((String) ken.nextElement()).append("年");
            if (ken.hasMoreElements()) {
                sb.append((String) ken.nextElement()).append("月");
                if (ken.hasMoreElements()) {
                    sb.append((String) ken.nextElement()).append("日");
                    strDate = sb.toString();
                }
            }
        }

        return strDate;
    }

    public static String parseDateEN(String strDate) {
        StringTokenizer ken = new StringTokenizer(strDate, "-");
        StringBuffer sb = new StringBuffer();
        if (ken.hasMoreElements()) {
            sb.append((String) ken.nextElement()).append("y");
            if (ken.hasMoreElements()) {
                sb.append((String) ken.nextElement()).append("m");
                if (ken.hasMoreElements()) {
                    sb.append((String) ken.nextElement()).append("d");
                    strDate = sb.toString();
                }
            }
        }

        return strDate;
    }

    public static String thisDate(Calendar cal, String strFormat) {
        java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(
                strFormat);

        return format.format(cal.getTime());
    }

    /**
     * 得到本月的第一天
     *
     * @return
     */
    public static String getMonthFirstDay(String formatStr) {
        /*Calendar calendar = DateTool.getCalendarInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar
                .getActualMinimum(Calendar.DAY_OF_MONTH));
        java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(
                formatStr);
        return format.format(calendar.getTime());*/

        Calendar cale = DateTool.getCalendarInstance();
        // 获取当月第一天和最后一天
        SimpleDateFormat format = new SimpleDateFormat(formatStr);
        String firstday, lastday;
        // 获取前月的第一天
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, 0);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        firstday = format.format(cale.getTime());
        return firstday;
    }

    /**
     * 得到本月的最后一天
     *
     * @return
     */
    public static String getMonthLastDay(String formatStr) {
        /*Calendar calendar = DateTool.getCalendarInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar
                .getActualMaximum(Calendar.DAY_OF_MONTH));
        java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(
                formatStr);
        return format.format(calendar.getTime());*/

        Calendar cale = DateTool.getCalendarInstance();
        // 获取当月第一天和最后一天
        SimpleDateFormat format = new SimpleDateFormat(formatStr);
        String firstday, lastday;
        // 获取前月的最后一天
        cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, 1);
        cale.set(Calendar.DAY_OF_MONTH, 0);
        lastday = format.format(cale.getTime());
        return lastday;
    }


    /**
     * 将字符串格式的日期转换为timestamp格式的
     *
     * @param date 日期格式为yyyy-MM-dd 或者 yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static Timestamp string2timestamp(String date) {
        if (date == null) return null;
        try {
            if (date.trim().length() == 10) {
                date += " 00:00:00";
            }
            return Timestamp.valueOf(date);
        } catch (Exception e) {
            return null;
        }
    }

    public static String timestamp2String(Timestamp timestamp) {
        return DateTool.date2String(timestamp, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * DateUtil constructor comment.
     */
    public DateUtils() {
        super();
    }

    /**
     * 返回指定的时间段内的有所日期
     *
     * @param startDate 开始时间,例:2016-02-25
     * @param endDate   结束时间,例:2016-03-05
     * @return
     */
    public static String[] dateSplit(String startDate, String endDate) {
        String[] ar = {};
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date newstartDate;
        try {
            newstartDate = simpleDateFormat.parse(startDate);
            Date newendDate = simpleDateFormat.parse(endDate);
            List<String> dateList = new ArrayList<String>();
            Long spi = newendDate.getTime() - newstartDate.getTime();
            Long step = spi / (24 * 60 * 60 * 1000);// 相隔天数
            List<Date> newdateList = new ArrayList<Date>();
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            newdateList.add(newstartDate);
            dateList.add(startDate);
            for (int i = 1; i <= step; i++) {
                dateList.add(formatter.format(new Date(newdateList.get(i - 1).getTime() + (24 * 60 * 60 * 1000))));
                newdateList.add(new Date(newdateList.get(i - 1).getTime() + (24 * 60 * 60 * 1000)));// 比上一天+一
            }
            String[] strings = new String[dateList.size()];
            String[] array = dateList.toArray(strings);
            return array;
        } catch (ParseException e) {
            e.printStackTrace();
            return ar;
        }
    }

    /**
     * 获取当前日期之前或之后的日期
     *
     * @param days      之前日期负数，之后日期正数
     * @param strFormat
     * @return
     */
    public static String getDateByDaysStr(int days, String strFormat) {
        if (strFormat == null || "".equals(strFormat)) {
            strFormat = "yyyy-MM-dd";
        }
        java.text.SimpleDateFormat format = new java.text.SimpleDateFormat(
                strFormat);
        Calendar cal = DateTool.getCalendarInstance();
        cal.add(Calendar.DATE, days);

        return format.format(cal.getTime());
    }

    public static Date getTodayBegin() {
        String today = DateUtils.getToDay("yyyy-MM-dd").concat(" 00:00:00");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateUtils.DATE_YMDHMS_SPLIT_14);
        try {
            return simpleDateFormat.parse(today);
        } catch (ParseException e) {
            throw new RuntimeException("日期转换出现异常，错误信息:" + e.getMessage());
        }
    }

    public static String getTodayBeginStr() {
        return DateUtils.getToDay("yyyy-MM-dd").concat(" 00:00:00");
    }

    public static String getTodayEndStr() {
        return DateUtils.getToDay("yyyy-MM-dd").concat(" 23:59:59");
    }

    public static String getDateBegin(String date) {
        if (null != null && date.length() >= 8) {

        }
        return DateUtils.getToDay("yyyy-MM-dd").concat(" 00:00:00");
    }

    public static LocalDateTime parseDateStr(String date, String pattern) {
        if (Strings.isNullOrEmpty(date)) {
            throw new IllegalArgumentException("【日期解析】传入日期不能为空");
        }
        if (Strings.isNullOrEmpty(pattern)) {
            pattern = DateUtils.DATE_YMDHMS_SPLIT_14;
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern);
        return LocalDateTime.parse(date, df);
    }

    public static Date stringToDate(String date, String pattern) {
        if (Strings.isNullOrEmpty(pattern)) {
            pattern = DateUtils.DATE_YMDHMS_SPLIT_14;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            return sdf.parse(date);
        } catch (ParseException e) {
            throw new IllegalArgumentException("日期转换失败，参数错误:" + date + "," + pattern);
        }

    }

    public static void main(String[] args) {
        System.out.println(DateUtils.getMonthFirstDay("yyyy-MM-dd 00:00:00"));
        System.out.println(DateUtils.getMonthLastDay("yyyy-MM-dd 23:59:59.999"));
        System.out.println(getTodayBegin());
    }

}
